from game.gameroom import GameRoom
from game.error import GameError

class BlackWhiteChess(GameRoom):
    type = 'blackwhite'
    max_players = 2
    roles = (('black', 1), ('white', 1))

    board = ['_'] * 64
    current = 'black'
    last_move = None

    def init_game(self):
        self.board = ['_'] * 64
        self.current = 'black'
        self.last_move = None
        self.set_chess(3, 3, 'b')
        self.set_chess(4, 4, 'b')
        self.set_chess(3, 4, 'w')
        self.set_chess(4, 3, 'w')
        self.caculate_x()

    def set_chess(self, x, y, chess):
        if x >= 0 and x < 8 and y >= 0 and y < 8:
            self.board[y * 8 + x] = chess

    def get_chess(self, x, y):
        if x >= 0 and x < 8 and y >= 0 and y < 8:
            return self.board[y * 8 + x]

        return None

    def check_and_move(self, x, y):
        if self.get_chess(x, y) != 'x':
            raise GameError('can not move')

        self.last_move = {'x':x, 'y':y}

        self._check_line(x, y, 1, 1, True)
        self._check_line(x, y, 1, 0, True)
        self._check_line(x, y, 1, -1, True)
        self._check_line(x, y, 0, 1, True)
        self._check_line(x, y, 0, -1, True)
        self._check_line(x, y, -1, 1, True)
        self._check_line(x, y, -1, 0, True)
        self._check_line(x, y, -1, -1, True)

        self.current = 'black' if self.current == 'white' else 'white'
        if not self.caculate_x():
            self.current = 'black' if self.current == 'white' else 'white'
            if not self.caculate_x():
                self.game_end()


    def caculate_x(self):
        can_move = False
        for x in range(8):
            for y in range(8):
                c = self.get_chess(x, y)
                if c in ['_', 'x']:
                    if self._check_and_mark(x, y):
                        self.set_chess(x, y, 'x')
                        can_move = True
                    else:
                        self.set_chess(x, y, '_')
        return can_move


    def _check_and_mark(self, x, y):
        if self._check_line(x, y, 1, 1): return True
        if self._check_line(x, y, 1, 0): return True
        if self._check_line(x, y, 1, -1): return True
        if self._check_line(x, y, 0, 1): return True
        if self._check_line(x, y, 0, -1): return True
        if self._check_line(x, y, -1, 1): return True
        if self._check_line(x, y, -1, 0): return True
        if self._check_line(x, y, -1, -1): return True
        return False


    def _check_line(self, x, y, step_x, step_y, move=False):
        my_color = self.current[0]
        other_color = 'b' if my_color == 'w' else 'w'

        xx = x + step_x
        yy = y + step_y

        if self.get_chess(xx, yy) != other_color:
            return False

        xx += step_x
        yy += step_y

        while self.get_chess(xx, yy) == other_color:
            xx += step_x
            yy += step_y

        if self.get_chess(xx, yy) != my_color:
            return False

        if move:
            self.set_chess(x, y, my_color)
            xx = x + step_x
            yy = y + step_y
            while self.get_chess(xx, yy) != my_color:
                self.set_chess(xx, yy, my_color)
                xx += step_x
                yy += step_y

        return True

    def update_game(self):
        self.broadcast('blackwhite', {
                            'board': ''.join(self.board),
                            'current': self.current,
                            'last_move': self.last_move,
                            })

    def _handle_blackwhite_move(self, player, message):
        if self.is_playing():
            role = self.get_player_role(player)
            if role == self.current:
                self.check_and_move(message['x'], message['y'])
                self.update_game()

    def _handle_blackwhite_refresh(self, player, message):
        self.update_game()

    def on_game_start(self):
        self.init_game()
        self.update_game()

